// 泛型
// 定义：泛型允许我们在定义函数、类或接口时，使用类型参数来表示未指定的类型，这些参数在具体使用时才被
// 指定具体的类型，泛型能让同一段代码使用于多种类型，同时任然保持类型的安全性

//1、泛型函数
// 下列的代码中的<T>就是泛型，(不一定非叫T)，设置泛型后即可在函数中使用T来表示该类型
function logData<T>(data: T): T {
    console.log(data);
    return data
}

logData<number>(100)    //这里泛型被定义为数字型
logData<string>('hello')   //这里泛型被定义为字符串
// 2、泛型可以有多个
function printData<T, U>(data1: T, data2: U): T | U {
    return Date.now() % 2 ? data1:data2
}
printData<number,boolean>(1999,false)    //这里泛型被定义为数字型和布尔型
printData<string,object>('hello',{})   //这里泛型被定义为字符串和对象

// 3、泛型接口
interface PersonInfoMsg<T>{
    name:string,
    age:number,
    extraInfo:T
}
let oppo:PersonInfoMsg<string>={
    name:'雨师篁',
    age:28,
    extraInfo:'肾虚老阿姨'
}
type JobInfo = {
    title:string,
    company:string
}
let leyan:PersonInfoMsg<JobInfo>={
    name:'雨师篁',
    age:28,
    extraInfo:{
        title:'菜鸡',
        company:'肾虚'
    }
}
// 4、泛型类
class Canyon<T>{
    constructor(
        public name:string,
        public age:number,
        public extraInfo:T
    ){}
    speak(){
        console.log('我是泛型类');
    }
}

const dwg = new Canyon<number>('DWGConyon',22,666)